package com.littleII.biz.impl;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.littleII.biz.SoftBiz;
import com.littleII.dao.SoftDAO;
import com.littleII.entity.DownloadURL;
import com.littleII.entity.SimpleSoft;
import com.littleII.enumber.DownloadType;
import com.littleII.enumber.Language;
import com.littleII.enumber.SoftType;
import com.littleII.enumber.Type;
import com.littleII.util.DateUtil;
import com.littleII.util.HttpClientUtil;

/**
 * 软件对象的业务实现类
 * @author littleII
 *
 */
@Service("softBiz")
public class SoftBizImpl implements SoftBiz{
	private static Logger logger = Logger.getLogger(SoftBizImpl.class);
	@Autowired
	private static int TIMEOUT;	//连接超时
	@Autowired
	private SoftDAO softDao;	//软件DAO
	@Autowired
	private static List<String> resourceURLs;	//所有资源站点的URL

	private int failCount = 0;

	private int index = 0;
	private int pageIndex = 1;
	private String next = "下一页";

	/**
	 * @return the softDao
	 */
	public SoftDAO getSoftDao() {
		return softDao;
	}
	/**
	 * @param softDao the softDao to set
	 */
	public void setSoftDao(SoftDAO softDao) {
		this.softDao = softDao;
	}
	/**
	 * @return the tIMEOUT
	 */
	public static int getTIMEOUT() {
		return TIMEOUT;
	}
	/**
	 * @param tIMEOUT the tIMEOUT to set
	 */
	public static void setTIMEOUT(int tIMEOUT) {
		TIMEOUT = tIMEOUT;
	}

	/**
	 * @return the resourceURLs
	 */
	public static List<String> getResourceURLs() {
		return resourceURLs;
	}


	/**
	 * @param resourceURLs the resourceURLs to set
	 */
	public static void setResourceURLs(List<String> resourceURLs) {
		SoftBizImpl.resourceURLs = resourceURLs;
	}


	public void getAllResource(){
		for (String resourceURL : resourceURLs) {
//			getresource(resourceURL);
			getresource2(resourceURL);
		}
	}

	private void getresource2(String resourceURL) {
		// soft/69999.html
		for (int i = 1;; i++) {
			long start = new Date().getTime();
			try {
				String url = resourceURL + "soft/" + i + ".html";
				SimpleSoft soft = new SimpleSoft();
				soft.setDetailURL(url);
				Document doc = Jsoup.connect(url).timeout(TIMEOUT).get();
				Elements infoDetails = doc.select(".info-detail tr td");
				//设置软件名
				soft.setName(doc.select(".hd h1").text());
				//设置软件简要说明
				soft.setSimpleDesc(doc.select(".soft-intro-con").text());
				//设置软件的详细说明
//				setDesc(doc, soft, resourceURL);
				//设置软件类别
				setsType(doc, soft);
				for (Element infoDetail : infoDetails) {
					// 设置简单属性
					setSoftAttribute(soft, infoDetail);
				}
				// 设置下载地址
				getDownLoadURL(doc, soft, resourceURL);
				logger.info(url);
				logger.info(soft);
				logger.info(new Date().getTime()-start);
				//保存软件记录
				if(checkSoft(soft)){
					softDao.saveOrUpdate(soft);
				}
			} catch (IOException e) {
				failCount++;
//				if(failCount < 5)
//				e.printStackTrace();
				continue;
			}
		}
	}
	/**
	 * 检查
	 * @param soft
	 * @return
	 */
	private boolean checkSoft(SimpleSoft soft) {
		return true;
	}
	/**
	 * 设置软件类别
	 * @param doc
	 * @param soft
	 */
	private void setsType(Document doc, SimpleSoft soft) {
		Elements types = doc.select(".crumb a[href]");
		soft.setsType(Type.byLabel(types.get(2).text()));

	}


	/**
	 * 设置软件的详细说明
	 * @param doc
	 * @param soft
	 * @param resourceURL
	 * @throws IOException
	 */
	private void setDesc(Document doc, SimpleSoft soft, String resourceURL) throws IOException {
		String href = doc.select(".soft-intro-more a[href]").first().attr("href");
		String url = resourceURL + StringUtils.removeStart(href,"..");
		Document d = Jsoup.connect(url).timeout(TIMEOUT).get();
		soft.setsDesc(d.select(".morew").html());
	}


	/**
	 * 设置简单属性:
	 * <pre>
	 * 	软件大小
	 * 	软件性质
	 * 	更新时间
	 * 	应用平台
	 * 	开 发 商
	 * </pre>
	 * @param soft
	 * @param infoDetail
	 */
	private void setSoftAttribute(SimpleSoft soft, Element infoDetail){
		String[] array = infoDetail.text().split("：");

		String key = array[0];
		String value = "";
		if(array.length>1){
			value = array[1];
		}
		if(key.equals("软件大小")){
			String[] arr = value.split(" ");
			soft.setSize(arr[0]);
			soft.setUnit(arr[1]);
			return;
		}
		if(key.equals("软件性质")){
			soft.setType(SoftType.byLabel(value));
			return;
		}
		if(key.equals("更新时间")){
			soft.setLastModifyTime(DateUtil.StringToDate(value));
			return;
		}
		if(key.equals("开 发 商")){
			soft.setOfficialWebsiteURL(infoDetail.select("a[href]").attr("href"));
			return;
		}
		if(key.equals("应用平台")){
			soft.setOe(value);
			return;
		}
		if(key.equals("下载次数")){
			soft.setDownloadCount(value);
			return;
		}
		if(key.equals("软件语言")){
			soft.setLanguage(Language.byLabel(value));
			return;
		}
		if(key.equals("软件语言")){
			soft.setLanguage(Language.byLabel(value));
			return;
		}
	}



	private void getresource(String resourceURL) {
//		http://www.skycn.com/sort/sort010000_indate_DESC_1.html
		String url = "http://www.skycn.com/sort/sort010000_indate_DESC_1.html";
		try {
			List<SimpleSoft> softs = new ArrayList<SimpleSoft>();
			Document doc = Jsoup.connect(url).timeout(TIMEOUT).get();
//			Map<String, Object> map = HttpClientUtil.get(url,"GBK");
//			Document doc = Jsoup.parse((String) map.get("responseBody"));
			/*List<SimpleSoft> softs = */getSoftsByDoc(doc,resourceURL,softs);
//			logger.info(doc);

			while(true){
				String nextURL = doc.select("a[href]:contains(" + next + ")").attr("href");
				if(StringUtils.isNotBlank(nextURL)){
					logger.info("pageIdex:" + ++pageIndex);
					doc = Jsoup.connect("http://www.skycn.com/sort/"+nextURL).timeout(TIMEOUT).get();
					getSoftsByDoc(doc,resourceURL,softs);
				}else{
					break;
				}
			}
			logger.info("over!");
		} catch (SocketTimeoutException e) {
			logger.error("超时!");
		}catch (IOException e) {
			e.printStackTrace();
		}
	}


	private List<SimpleSoft> getSoftsByDoc(Document doc, String resourceURL, List<SimpleSoft> softs) throws IOException {
		Element boxBody = doc.select("#clsList2 .boxBody").get(0);
		Elements as = boxBody.select("dt a[title]");//包含有软件名称、详细说明的URL
		Elements dds = boxBody.select("dd");	//包含软件性质(共享 or 免费) 、更新时间、软件的大小、简要说明

		logger.info("Size: " + as.size());
		for (int i=0;i<as.size();i++) {
			logger.info("index:" + ++index);
			//设置软件的软件名称、详细说明的URL
			Element a = as.get(i);
			SimpleSoft soft = new SimpleSoft();
			soft.setDetailURL(a.attr("href"));
			soft.setName(a.attr("title"));

			//设置软件的性质(共享 or 免费) 、更新时间、软件的大小、简要说明
			Element dd = dds.get(i);
			String msg = dd.text();
			String[] strs = msg.split("\\|");
			soft.setType(SoftType.byLabel(strs[0]));
			soft.setLastModifyTime(DateUtil.StringToDate(strs[1].split("：")[1]));
			soft.setSize(strs[3].split(" ")[0].split("：")[1]);
			soft.setUnit(strs[3].split(" ")[1]);
			soft.setSimpleDesc(dd.select("p").text());
			//设置下载地址
//			getDownLoadURL(soft,resourceURL);
//			logger.info(soft);
			softs.add(soft);
		}

		return softs;
	}

	private void getDownLoadURL(Document document, SimpleSoft soft, String resourceURL) throws IOException {
		boolean hasDownURL = true;
//		Document document = Jsoup.connect(StringUtils.removeStart(soft.getDetailURL(),"..")).get();
//		Document document = Jsoup.connect(resourceURL + StringUtils.removeStart(soft.getDetailURL(),"..")).get();

//		Map<String, Object> responseMap = HttpClientUtil.get(resourceURL + StringUtils.removeStart(soft.getDetailURL(),".."),"GBK");
//		Document document = Jsoup.parse((String) responseMap.get("responseBody"));

		Elements downList = document.select(".down-list");

		String downURL = downList.select("a").attr("href");//包含官方下载地址的
		if(StringUtils.isBlank(downURL)){
			hasDownURL = false;
			//普通下载地址
			Elements downurl = document.select(".downurl");
			downURL = downurl.select("script").attr("src");
			String url = resourceURL + downURL;
//			logger.info(url);
			Map<String, Object> map = HttpClientUtil.get(url,"GBK");
			String responseBody = (String) map.get("responseBody");
			Document doc = Jsoup.parse(responseBody);//bright
			Elements es = doc.select("table:has(.down-list)");

			String recommend = doc.select(".bright").text();//推荐下载点,电信下载点|联通/网通下载点|移动/长宽下载点
			DownloadType recommendType = DownloadType.getSoftTypeByLabel(recommend);	//推荐类型
			List<DownloadURL> downloadURLs = new ArrayList<DownloadURL>();
			for(Element e : es){
				//下载点的类型描述
				String desc = e.select("h1").text();

				//下载点类型
				DownloadType type = DownloadType.getSoftTypeByLabel(desc);

				for(Element downUrls : e.select("a[href]")){
					String downURL2 = downUrls.attr("href");
					//下载点名字
					String name = downUrls.text();
					DownloadURL downloadURL = new DownloadURL();
					downloadURL.setDownloadType(type);
					downloadURL.setsDesc(name);
					downloadURL.setUrl(downURL2);
					downloadURLs.add(downloadURL);
					//设置默认的下载地址
					if(!hasDownURL && type==recommendType && StringUtils.isNotBlank(downURL2)){
						if(name.indexOf("浙江")!=-1 || name.indexOf("上海")!=-1 || name.indexOf("江苏")!=-1){
							downURL = downURL2;
							hasDownURL = true;
						}
					}
				}
			}
			//设置所有的下载地址
			soft.setDownloadURLs(downloadURLs);
		}
		//设置默认的下载地址
		soft.setDownloadURL(downURL);
	}


	/**
	 * 测试
	 */
	public void test() {
		try {
			int b = 0;
			if(b==0)return;
			String val = "QQ";
			Document doc = Jsoup.connect("http://www.skycn.com/search.php").timeout(TIMEOUT)
			.data("ss_name", val).get();
//			Element content = doc.getElementById("content");
			Element boxBody = doc.select(".boxBody").get(0);
			Elements as = boxBody.select("dt a[title]");
			Elements dds = boxBody.select("dd");
			Map<Integer, SimpleSoft> softs = new HashMap<Integer, SimpleSoft>();

			logger.info("size:" + as.size());

			for (int i=0;i<as.size();i++) {
				Element a = as.get(i);
				SimpleSoft soft = softs.get(i)==null ? new SimpleSoft() : softs.get(i);
				soft.setDetailURL(a.attr("href"));
				soft.setName(a.attr("title"));
				Element dd = dds.get(i);
				soft.setOe(dd.select("font").attr("title"));
				String msg = dd.text();
//				System.out.println(msg);
				String[] strs = msg.split("\\|");
				soft.setType(SoftType.byLabel(strs[1]));
				soft.setLastModifyTime(DateUtil.StringToDate(strs[2].split("：")[1]));
				soft.setSize(strs[4].split(" ")[0].split("：")[1]);
				soft.setUnit(strs[4].split(" ")[1]);
				//getDownloadURL
				Document document = Jsoup.connect("http://www.skycn.com/"+soft.getDetailURL()).get();
				Elements downList = document.select(".down-list");

				String downURL = downList.select("a").attr("href");//包含官方下载地址的
				if(StringUtils.isBlank(downURL)){
					//普通下载地址
					Elements downurl = document.select(".downurl");
					downURL = downurl.select("script").attr("src");
					String url = "http://www.skycn.com/"+downURL;
//					logger.info(url);
					Map<String, Object> map = HttpClientUtil.get(url,"GBK");
					String responseBody = (String) map.get("responseBody");
					Document rbDoc = Jsoup.parse(responseBody);//bright
					String recommend = rbDoc.select(".bright").text();//推荐下载点,电信下载点|联通/网通下载点|移动/长宽下载点

					//找到下一个"电信下载点"的上级的上级,直到<td>
					Element td = rbDoc.select("td:contains(" + recommend + ")").first();
					downURL = td.select("a[href]").first().attr("href");
				}
				soft.setDownloadURL(downURL);
				logger.info(soft);
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
		logger.info("test");
	}
	public void get(){
		String hql = "from SimpleSoft";
		List<SimpleSoft> softs = softDao.getObjList(hql, null);
		System.out.println(softs);
	}
}
